// 1.=======
function test() {
    console.log(b);
    if (a) {
        var b = 100;
    }
    console.log(b);
    c = 234;
    console.log(c);
}
var a;
test();
a = 10;
console.log(c);

 /**
  1. 生成GO
  GO: {
    a: undefined,
    test: function test() {},
    c: undefined
   }
  JavaScript中变量如果未经声明就赋值，会默认将变量挂载到window对象上，这也就是所谓的imply global。c就是imply global。

  2. test执行，生成test的AO
    // AO还会存储[[scope]]属性，存储AO的作用域链
    AO: {
        b: undefined,
        [[scope]]: [TestAO, GO]
    }
    有同学会问，if(a)为false，if内部不会执行，那test的AO中为什么还会有b啊？
    预编译并不是执行，它只不过把变量、函数等进行提升，只有在执行时，才会设计代码逻辑的判断。
  3. 分析test函数执行
    console.log(b) // AO中b为undefined
    if (a) // AO中无a，沿[[scope]]找到GO中的a，值为undefined
    b = 100; // 不执行
    console.log(b) // undefined
    c = 234; // AO中没有c属性，沿[[scope]]找到GO中的c修改为234
    console.log(c) // 打印的是GO中的c，234
    // test执行完毕，AO销毁

  4. 分析剩余代码：
    a = 10; // GO中的a修改为10
    console.log(c) // GO中c值为234，234

*/

// 2.=======+++++++++++++++++++
console.log("// 2.=======+++++++++++++++++++")
var foo = 1;
function bar() {
    console.log(foo);  
    if (!foo) {
        var foo = 10;
    }
    console.log(foo); 
}

bar();

// 3.=======+++++++++++++++++++
console.log("// 3.=======+++++++++++++++++++")
var a = 1;
function b() {
    console.log(a);  
    function a() { }
    var a = 10;
    
}
b();
console.log(a); 
// 说明 function大于变量

// 4.=======+++++++++++++++++++
console.log("// 4.=======+++++++++++++++++++")   

console.log(foo4); 
foo4(); 
var foo4 = "A";
console.log(foo4)  
var foo4 = function () {
    console.log("B");
}
console.log(foo4); 
foo4(); 
function foo4(){
    console.log("C");
}
console.log(foo4)  
foo4(); 

// 5.=======+++++++++++++++++++
console.log("// 5.=======+++++++++++++++++++")  
var foo5 = 1;
function bar5(a) {
    var a1 = a;
    var a = foo5;
    function a() {
        console.log(a); 
    }
    a1();
}

bar5(3);